package td;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import utils.FileUtils;
import bbb.sss.Utils;
import dc.exam.TableInfo;

public class Main {

	public static void main(String[] args) {
		// System.out.println(test6(1.0/16, 0.2, 2, 5));
		// System.out.println(test6(0.27, -0.1, 180, 320));

		// String path = "C:\\Users\\Administrator\\Desktop\\3D\\AAA\\";
		//
		// for (int i = 0; i <= 50; i++) {
		// double discount = i / 100.0;
		// TableInfo ti = test6(0.27, discount, 180, 320);
		// String dp = path + i + ".htm";
		// FileUtils.writeFile(dp, ti.toString(), "gbk");
		// }
		//		
		// for (int i = 1; i < 11; i++) {
		// System.out.println(i + " > " + Math.pow(i, 3));
		// }
		// test3();
		String path = "C:\\Users\\Administrator\\Desktop\\aa.htm";
		TableInfo ti = test7(0.27, 180, 320);
		FileUtils.writeFile(path, ti.toString(), "gbk");
	}

	public static void test1() {
		int count = 10;
		int i = 3;

		while (i <= count) {
			long cc = Utils.c(i, 3);
			System.out.println(cc * 2);
			i++;
		}

	}

	public static void test2() {
		int count = 1000;
		int i = 1;

		// TD td1 = new TD();
		// td1.setCode(222);
		// TD td2 = new TD();
		// td2.setCode(123);
		//		
		// System.out.println(td2.contain(td1));
		Map<Integer, Integer> counter = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> numberCounter = new TreeMap<Integer, Integer>();
		TD cur = new TD();
		cur.setCode(0);
		while (i <= count) {
			int cc = Utils.randomNumber(1000) - 1;
			TD td = new TD();
			td.setCode(cc);
			int fc = td.contain(cur);
			// System.out.println(cc + " : " + Arrays.toString(td.getNumbers())
			// + " ========== " + fc);
			if (counter.get(fc) == null) {
				counter.put(fc, 1);
			} else {
				counter.put(fc, counter.get(fc) + 1);
			}

			List<Integer> nn = td.getNumbers();
			for (int n : nn) {
				if (numberCounter.get(n) == null) {
					numberCounter.put(n, 1);
				} else {
					numberCounter.put(n, numberCounter.get(n) + 1);
				}
			}

			cur.setCode(cc);
			i++;
		}

		for (Integer key : counter.keySet()) {
			System.out.println(key + " ===> " + counter.get(key));
		}

		for (Integer key : numberCounter.keySet()) {
			System.out.println(key + " ===> " + numberCounter.get(key));
		}
	}

	public static void mapAdd(Map<Integer, Integer> map, Integer key,
			Integer acc) {
		Integer ret = map.get(key);
		if (ret == null) {
			map.put(key, acc);
		} else {
			map.put(key, ret + acc);
		}
	}

	public static void test3() {
		int count = 400;
		int i = 1;

		int[] allPosition = new int[1000];
		int[] onePosition = new int[1000];
		int[] thrPosition = new int[1000];
		int[] sixPosition = new int[1000];

		Map<Integer, Integer> allCounter = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> oneCounter = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> thrCounter = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> sixCounter = new TreeMap<Integer, Integer>();

		Map<Integer, Integer> allStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> oneStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> thrStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> sixStep = new TreeMap<Integer, Integer>();

		while (i <= count) {
			int cc = Utils.randomNumber(1000) - 1;
			TD td = new TD();
			td.setCode(cc);

			TD combTd = td.combTD();
			if (td.type() == TD.THR_COMB) {
				mapAdd(thrCounter, combTd.getCode(), 1);
				mapAdd(thrStep, combTd.getCode(), i
						- thrPosition[combTd.getCode()]);
				thrPosition[combTd.getCode()] = i;
			}

			if (td.type() == TD.SIX_COMB) {
				mapAdd(sixCounter, combTd.getCode(), 1);
				mapAdd(sixStep, combTd.getCode(), i
						- sixPosition[combTd.getCode()]);
				sixPosition[combTd.getCode()] = i;
			}

			if (td.type() == TD.ONE_COMB) {
				mapAdd(oneCounter, combTd.getCode(), 1);
				mapAdd(oneStep, combTd.getCode(), i
						- onePosition[combTd.getCode()]);
				onePosition[combTd.getCode()] = i;
			}

			mapAdd(allCounter, cc, 1);
			mapAdd(allStep, cc, i - allPosition[cc]);
			allPosition[td.getCode()] = i;

			i++;
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("分布：");
		for (Integer key : allStep.keySet()) {
			System.out.println(key + " ===> " + allStep.get(key) + " count: "
					+ allCounter.get(key) + " avg : " + allStep.get(key) * 1.0
					/ allCounter.get(key));
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组一分布：");
		for (Integer key : oneStep.keySet()) {
			System.out.println(key + " ===> " + oneStep.get(key) + " count: "
					+ oneCounter.get(key) + " avg : " + oneStep.get(key) * 1.0
					/ oneCounter.get(key));
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组三分布：");
		for (Integer key : thrStep.keySet()) {
			System.out.println(key + " ===> " + thrStep.get(key) + " count: "
					+ thrCounter.get(key) + " avg : " + thrStep.get(key) * 1.0
					/ thrCounter.get(key));
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组六分布：");
		for (Integer key : sixStep.keySet()) {
			System.out.println(key + " ===> " + sixStep.get(key) + " count: "
					+ sixCounter.get(key) + " avg : " + sixStep.get(key) * 1.0
					/ sixCounter.get(key));
		}
	}

	public static void test4() {
		int count = 400000;
		int i = 1;

		int curType = TD.ERR_COMB;
		int curCount = 0;

		int[] counts = new int[7];
		int[] minLenth = new int[7];
		int[] maxLenth = new int[7];
		int[] sumLength = new int[7];

		StringBuffer oneSB = new StringBuffer();
		StringBuffer thrSB = new StringBuffer();
		StringBuffer sixSB = new StringBuffer();

		Map<Integer, Integer> oneStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> thrStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> sixStep = new TreeMap<Integer, Integer>();

		while (i <= count) {
			int cc = Utils.randomNumber(1000) - 1;
			// System.out.println(cc);
			TD td = new TD();
			td.setCode(cc);
			int type = td.type();

			if (type != curType) {
				if (curType == TD.ONE_COMB) {
					mapAdd(oneStep, curCount, 1);
					oneSB.append("" + curCount).append("\r\n");
				} else if (curType == TD.THR_COMB) {
					mapAdd(thrStep, curCount, 1);
					thrSB.append("" + curCount).append("\r\n");
				} else if (curType == TD.SIX_COMB) {
					mapAdd(sixStep, curCount, 1);
					sixSB.append("" + curCount).append("\r\n");
				}

				if (curType != TD.ERR_COMB) {
					counts[curType]++;
					if (minLenth[curType] == 0 || minLenth[curType] > curCount) {
						minLenth[curType] = curCount;
					}
					if (maxLenth[curType] < curCount) {
						maxLenth[curType] = curCount;
					}
					sumLength[curType] += curCount;
				}

				curType = type;
				curCount = 1;
			} else {
				curCount++;
			}

			i++;
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组一连续：");
		System.out.println("总数:" + sumLength[TD.ONE_COMB] + "/"
				+ counts[TD.ONE_COMB] + " 最小：" + minLenth[TD.ONE_COMB] + " 最大："
				+ maxLenth[TD.ONE_COMB] + " 平均："
				+ (sumLength[TD.ONE_COMB] * 1.0 / counts[TD.ONE_COMB]));
		for (Integer key : oneStep.keySet()) {
			System.out.println(key + " ===> " + oneStep.get(key));
		}
		// System.out.println(oneSB.toString());

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组三连续：");
		System.out.println("总数:" + sumLength[TD.THR_COMB] + "/"
				+ counts[TD.THR_COMB] + " 最小：" + minLenth[TD.THR_COMB] + " 最大："
				+ maxLenth[TD.THR_COMB] + " 平均："
				+ (sumLength[TD.THR_COMB] * 1.0 / counts[TD.THR_COMB]));
		for (Integer key : thrStep.keySet()) {
			System.out.println(key + " ===> " + thrStep.get(key));
		}
		// System.out.println(thrSB.toString());

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组六连续：");
		System.out.println("总数:" + sumLength[TD.SIX_COMB] + "/"
				+ counts[TD.SIX_COMB] + " 最小：" + minLenth[TD.SIX_COMB] + " 最大："
				+ maxLenth[TD.SIX_COMB] + " 平均："
				+ (sumLength[TD.SIX_COMB] * 1.0 / counts[TD.SIX_COMB]));
		for (Integer key : sixStep.keySet()) {
			System.out.println(key + " ===> " + sixStep.get(key));
		}
		// System.out.println(sixSB.toString());
	}

	public static void test5() {
		int count = 20;
		int i = 1;

		int[] position = new int[7];
		int[] counts = new int[7];
		int[] minLenth = new int[7];
		int[] maxLenth = new int[7];
		int[] sumLength = new int[7];

		StringBuffer oneSB = new StringBuffer();
		StringBuffer thrSB = new StringBuffer();
		StringBuffer sixSB = new StringBuffer();

		Map<Integer, Integer> oneStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> thrStep = new TreeMap<Integer, Integer>();
		Map<Integer, Integer> sixStep = new TreeMap<Integer, Integer>();

		while (i <= count) {
			int cc = Utils.randomNumber(1000) - 1;
			TD td = new TD(cc);
			System.out.println(cc);
			int type = td.type();

			int length = i - position[type];
			if (type == TD.ONE_COMB) {
				mapAdd(oneStep, length, 1);
				oneSB.append("" + length).append("\r\n");
			} else if (type == TD.THR_COMB) {
				mapAdd(thrStep, length, 1);
				thrSB.append("" + length).append("\r\n");
			} else if (type == TD.SIX_COMB) {
				mapAdd(sixStep, length, 1);
				sixSB.append("" + length).append("\r\n");
			}

			if (type != TD.ERR_COMB) {
				if (minLenth[type] == 0 || minLenth[type] > length) {
					minLenth[type] = length;
				}
				if (maxLenth[type] < length) {
					maxLenth[type] = length;
				}
				sumLength[type] += length;
			}
			counts[type]++;
			position[type] = i;

			i++;
		}

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组一连续：");
		System.out.println("总数:" + sumLength[TD.ONE_COMB] + "/"
				+ counts[TD.ONE_COMB] + " 最小：" + minLenth[TD.ONE_COMB] + " 最大："
				+ maxLenth[TD.ONE_COMB] + " 平均："
				+ (sumLength[TD.ONE_COMB] * 1.0 / counts[TD.ONE_COMB]));
		for (Integer key : oneStep.keySet()) {
			System.out.println(key + " ===> " + oneStep.get(key));
		}
		// System.out.println(oneSB.toString());

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组三连续：");
		System.out.println("总数:" + sumLength[TD.THR_COMB] + "/"
				+ counts[TD.THR_COMB] + " 最小：" + minLenth[TD.THR_COMB] + " 最大："
				+ maxLenth[TD.THR_COMB] + " 平均："
				+ (sumLength[TD.THR_COMB] * 1.0 / counts[TD.THR_COMB]));
		for (Integer key : thrStep.keySet()) {
			System.out.println(key + " ===> " + thrStep.get(key));
		}
		// System.out.println(thrSB.toString());

		System.out
				.println("-------------------------------------------------------------");
		System.out.println("组六连续：");
		System.out.println("总数:" + sumLength[TD.SIX_COMB] + "/"
				+ counts[TD.SIX_COMB] + " 最小：" + minLenth[TD.SIX_COMB] + " 最大："
				+ maxLenth[TD.SIX_COMB] + " 平均："
				+ (sumLength[TD.SIX_COMB] * 1.0 / counts[TD.SIX_COMB]));
		for (Integer key : sixStep.keySet()) {
			System.out.println(key + " ===> " + sixStep.get(key));
		}
		// System.out.println(sixSB.toString());
	}

	public static TableInfo test6(double rate, double discount, double oneCost,
			double oneAward) {
		List<String> header = new ArrayList<String>();
		List<List<String>> info = new ArrayList<List<String>>();
		header.add("期数");
		header.add("本期注数");
		header.add("本期消费");
		header.add("本期概率");
		header.add("累计注数");
		header.add("累计消费");
		header.add("累计概率");
		header.add("中奖金额");
		header.add("净利润");
		header.add("利润率");

		long total = 0;
		long currentCount = 0;
		for (int i = 1; i <= 50; i++) {
			if (i == 1) {
				currentCount = 1;
				total = 1;
			} else {
				currentCount = (long) Math.ceil(oneCost * total
						* (1 + discount)
						/ (oneAward - oneCost - oneCost * discount));
				total += currentCount;
			}
			List<String> c = new ArrayList<String>();
			c.add("" + i);
			c.add("" + currentCount);
			c.add("" + currentCount * oneCost);
			c.add("" + scale(currentRate(rate, i), 4));
			c.add("" + total);
			c.add("" + total * oneCost);
			c.add("" + scale(aheadRate(rate, i), 4));
			c.add("" + currentCount * oneAward);
			c.add("" + (currentCount * oneAward - total * oneCost));
			c.add(""
					+ scale((currentCount * oneAward - total * oneCost)
							/ (total * oneCost), 3));
			info.add(c);
		}

		return new TableInfo(header, info);
	}

	public static TableInfo test7(double rate, double oneCost, double oneAward) {
		List<String> header = new ArrayList<String>();
		List<List<String>> info = new ArrayList<List<String>>();
		header.add("期数");
		header.add("本期注数");
		header.add("本期消费");
		header.add("本期概率");
		header.add("累计注数");
		header.add("累计消费");
		header.add("累计概率");
		header.add("中奖金额");
		header.add("净利润");
		header.add("利润率");

		long[] ccl = new long[] { 0, 0, 0, 0, 1, 1, 3, 7, 15, 13, 21, 34 };
		long total = 0;
		long currentCount = 0;
		for (int i = 1; i <= 9; i++) {
			currentCount = ccl[i - 1];
			total += currentCount;

			List<String> c = new ArrayList<String>();
			c.add("" + i);
			c.add("" + currentCount);
			c.add("" + currentCount * oneCost);
			c.add("" + scale(currentRate(rate, i), 4));
			c.add("" + total);
			c.add("" + total * oneCost);
			c.add("" + scale(aheadRate(rate, i), 4));
			c.add("" + currentCount * oneAward);
			c.add("" + (currentCount * oneAward - total * oneCost));
			try {
				c.add(""
						+ scale((currentCount * oneAward - total * oneCost)
								/ (total * oneCost), 3));
			} catch (Exception e) {
			}
			info.add(c);
		}

		return new TableInfo(header, info);
	}

	public static Double scale(Double number, int bits) {
		BigDecimal b = new BigDecimal(number);
		return b.setScale(bits, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static Double aheadRate(double singleRate, int count) {
		return 1.0 - Math.pow((1.0 - singleRate), count);
	}

	public static Double currentRate(double singleRate, int count) {
		return singleRate * Math.pow((1.0 - singleRate), count - 1);
	}
}
